<template>
  <div id="Box">
    <div id="mapContainer"></div>
    <div id="toolbar">
      <span @click="startDraw(DrawType.CIRCLE)"> 圆形 </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { markRaw, onMounted, reactive } from "vue";
import { useCesium } from "../composables";

import * as Cesium from "cesium";
import { DrawType } from "../composables/ENUM";
const { initViewer, windowPoint2Cartesian3, ByDirectionAndLen } =
  useCesium("mapContainer");

const datas = reactive<{
  viewer: Cesium.Viewer | undefined;
  isDrawing: boolean;
  isEditing: boolean;
  isDown: boolean;
}>({
  viewer: undefined,
  isDrawing: false,
  isEditing: false,
  isDown: false,
});

const draw = reactive<{
  start: Cesium.Cartesian3;
  end: Cesium.Cartesian3;
  drawType: DrawType;
  clickOnce: boolean;
}>({
  start: new Cesium.Cartesian3(),
  end: new Cesium.Cartesian3(),
  drawType: DrawType.CIRCLE,
  clickOnce: false,
});

const ds = new Cesium.CustomDataSource();
const drawCircle = () => {
  draw.clickOnce = true;
  ds.entities.add({
    id: "drawTemp",
    position: draw.start!,
    ellipse: {
      semiMajorAxis: new Cesium.CallbackProperty(
        () => Cesium.Cartesian3.distance(draw.start, draw.end),
        false
      ),
      semiMinorAxis: new Cesium.CallbackProperty(
        () => Cesium.Cartesian3.distance(draw.start, draw.end),
        false
      ),
      material: Cesium.Color.RED.withAlpha(0.5),
      height: 0, // 贴地
    },
  });
};

const startDraw = (type: DrawType) => {
  datas.isDrawing = true;
  draw.drawType = type;
};

const initHandler = () => {
  const viewer = datas.viewer!;
  const handler = viewer.screenSpaceEventHandler;

  handler.setInputAction((evt: any) => {
    const position = evt.position;
    const point = markRaw(windowPoint2Cartesian3(position));

    if (datas.isDrawing) {
      if (draw.drawType === DrawType.CIRCLE && !draw.clickOnce) {
        draw.start = point;
        draw.end = point;
        drawCircle();
      }
    } else {
      const feature = datas.viewer?.scene.pick(evt.position);
      if (feature) {
        const entity = feature.id as Cesium.Entity;
        const len = entity.ellipse?.semiMajorAxis?.getValue();
        const end = ByDirectionAndLen(entity.position?.getValue()!, 0, len);
        viewer.entities.removeAll();
        datas.isEditing = true;
        viewer.entities.add({
          id: "tpPoint",
          point: {
            pixelSize: 20,
          },
          position: new Cesium.CallbackPositionProperty(() => draw.end, false),
        });

        entity.ellipse!.semiMajorAxis = new Cesium.CallbackProperty(
          () => Cesium.Cartesian3.distance(draw.start, draw.end),
          false
        );
        entity.ellipse!.semiMinorAxis = new Cesium.CallbackProperty(
          () => Cesium.Cartesian3.distance(draw.start, draw.end),
          false
        );
      } else {
        viewer.entities.removeAll();
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  handler.setInputAction((evt: any) => {
    const position = evt.endPosition;
    if ((datas.isDown || datas.isDrawing) && position) {
      const point = markRaw(windowPoint2Cartesian3(position));
      draw.end = point;
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  handler.setInputAction((evt: any) => {
    if (datas.isDrawing) {
      datas.isDrawing = false;
      ds.entities.add({
        position: draw.start!,
        ellipse: {
          semiMajorAxis: Cesium.Cartesian3.distance(draw.start, draw.end),
          semiMinorAxis: Cesium.Cartesian3.distance(draw.start, draw.end),
          material: Cesium.Color.RED.withAlpha(0.5),
          height: 0, // 贴地
        },
      });
      ds.entities.removeById("drawTemp");
      draw.clickOnce = false;
    }
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

  handler.setInputAction((evt: any) => {
    const position = evt.position;
    const entity = datas.viewer?.scene.pick(position);
    if (datas.isEditing && entity) {
      datas.isDown = true;
      datas.viewer!.scene.screenSpaceCameraController.enableInputs = false;
    }
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

  handler.setInputAction((evt: any) => {
    datas.isDown = false;
    datas.viewer!.scene.screenSpaceCameraController.enableInputs = true;
  }, Cesium.ScreenSpaceEventType.LEFT_UP);
};

onMounted(() => {
  datas.viewer = markRaw(initViewer());
  datas.viewer.dataSources.add(ds);
  initHandler();
  // const entity = ds.entities.add({
  //   position: Cesium.Cartesian3.fromDegrees(116.397477, 39.908692, 0),
  //   name: "circle",
  //   ellipse: {
  //     semiMajorAxis: 5000,
  //     semiMinorAxis: 5000,
  //     material: Cesium.Color.RED.withAlpha(0.5),
  //     height: 0, // 贴地
  //   },
  // });

  datas.viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(116.397477, 39.908692, 18000),
    duration: 0,
  });
});
</script>

<style scoped lang="less">
#Box {
  #mapContainer {
    height: 100vh;
  }
  #toolbar {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 600px;
    height: 35px;
    background-color: rgb(252, 252, 252);
    display: flex;
    align-items: center;
    border-radius: 10px;
    padding: 0 10px;
    span {
      cursor: pointer;
    }
  }
}
</style>
